const { select, input, confirm } = require('@inquirer/prompts');
const fs = require('fs-extra');
const path = require('path');
const chalk = require('chalk');
const dotenv = require('dotenv');

// 加载环境变量
dotenv.config({ path: path.resolve(__dirname, '../../.env') });

class ExpressCrudGenerator {
    constructor() {
        this.config = {
            output: {
                controllersDir: path.resolve(__dirname, '../../src/controllers'),
                routesDir: path.resolve(__dirname, '../../src/routes'),
                middlewareDir: path.resolve(__dirname, '../../src/middleware'),
                validatorsDir: path.resolve(__dirname, '../../src/validators')
            }
        };
    }

    async getAvailableModels() {
        try {
            const modelsDir = path.resolve(__dirname, '../../src/models');
            const files = await fs.readdir(modelsDir);

            return files
                .filter(file => file.endsWith('.js') && file !== 'index.js')
                .map(file => ({
                    name: path.basename(file, '.js'),
                    value: path.basename(file, '.js'),
                    file: file
                }));
        } catch (error) {
            console.error(chalk.red('❌ 读取模型目录失败:'), error.message);
            return [];
        }
    }

    generateController(modelName) {
        const controllerName = `${modelName}Controller`;
        const content = `const { ${modelName} } = require('../models');
const { validationResult } = require('express-validator');
const logger = require('../utils/logger');

class ${controllerName} {
  /**
   * 获取列表
   */
  async getList(req, res) {
    try {
      const { page = 1, limit = 10, ...filters } = req.query;
      const offset = (page - 1) * limit;

      const { count, rows } = await ${modelName}.findAndCountAll({
        where: filters,
        limit: parseInt(limit),
        offset: parseInt(offset),
        order: [['created_at', 'DESC']]
      });

      res.json({
        success: true,
        data: {
          list: rows,
          pagination: {
            page: parseInt(page),
            limit: parseInt(limit),
            total: count,
            pages: Math.ceil(count / limit)
          }
        }
      });
    } catch (error) {
      logger.error('获取${modelName}列表失败:', error);
      res.status(500).json({
        success: false,
        message: '获取列表失败',
        error: error.message
      });
    }
  }

  /**
   * 获取详情
   */
  async getDetail(req, res) {
    try {
      const { id } = req.params;

      const item = await ${modelName}.findByPk(id);
      if (!item) {
        return res.status(404).json({
          success: false,
          message: '记录不存在'
        });
      }

      res.json({
        success: true,
        data: item
      });
    } catch (error) {
      logger.error('获取${modelName}详情失败:', error);
      res.status(500).json({
        success: false,
        message: '获取详情失败',
        error: error.message
      });
    }
  }

  /**
   * 创建记录
   */
  async create(req, res) {
    try {
      const errors = validationResult(req);
      if (!errors.isEmpty()) {
        return res.status(400).json({
          success: false,
          message: '参数验证失败',
          errors: errors.array()
        });
      }

      const data = req.body;
      const item = await ${modelName}.create(data);

      res.status(201).json({
        success: true,
        message: '创建成功',
        data: item
      });
    } catch (error) {
      logger.error('创建${modelName}失败:', error);
      res.status(500).json({
        success: false,
        message: '创建失败',
        error: error.message
      });
    }
  }

  /**
   * 更新记录
   */
  async update(req, res) {
    try {
      const { id } = req.params;
      const errors = validationResult(req);
      if (!errors.isEmpty()) {
        return res.status(400).json({
          success: false,
          message: '参数验证失败',
          errors: errors.array()
        });
      }

      const item = await ${modelName}.findByPk(id);
      if (!item) {
        return res.status(404).json({
          success: false,
          message: '记录不存在'
        });
      }

      const data = req.body;
      await item.update(data);

      res.json({
        success: true,
        message: '更新成功',
        data: item
      });
    } catch (error) {
      logger.error('更新${modelName}失败:', error);
      res.status(500).json({
        success: false,
        message: '更新失败',
        error: error.message
      });
    }
  }

  /**
   * 删除记录
   */
  async delete(req, res) {
    try {
      const { id } = req.params;

      const item = await ${modelName}.findByPk(id);
      if (!item) {
        return res.status(404).json({
          success: false,
          message: '记录不存在'
        });
      }

      await item.destroy();

      res.json({
        success: true,
        message: '删除成功'
      });
    } catch (error) {
      logger.error('删除${modelName}失败:', error);
      res.status(500).json({
        success: false,
        message: '删除失败',
        error: error.message
      });
    }
  }

  /**
   * 批量删除
   */
  async batchDelete(req, res) {
    try {
      const { ids } = req.body;

      if (!Array.isArray(ids) || ids.length === 0) {
        return res.status(400).json({
          success: false,
          message: '请选择要删除的记录'
        });
      }

      await ${modelName}.destroy({
        where: {
          id: ids
        }
      });

      res.json({
        success: true,
        message: \`成功删除 \${ids.length} 条记录\`
      });
    } catch (error) {
      logger.error('批量删除${modelName}失败:', error);
      res.status(500).json({
        success: false,
        message: '批量删除失败',
        error: error.message
      });
    }
  }
}

module.exports = new ${controllerName}();
`;

        return content;
    }

    generateRoutes(modelName) {
        const routeName = modelName.toLowerCase();
        const content = `const express = require('express');
const router = express.Router();
const ${modelName}Controller = require('../controllers/${modelName}Controller');
const { validate${modelName} } = require('../validators/${modelName}Validator');
const authMiddleware = require('../middleware/authMiddleware');

// 应用认证中间件
router.use(authMiddleware);

// 获取列表
router.get('/', ${modelName}Controller.getList);

// 获取详情
router.get('/:id', ${modelName}Controller.getDetail);

// 创建记录
router.post('/', validate${modelName}, ${modelName}Controller.create);

// 更新记录
router.put('/:id', validate${modelName}, ${modelName}Controller.update);

// 删除记录
router.delete('/:id', ${modelName}Controller.delete);

// 批量删除
router.delete('/', ${modelName}Controller.batchDelete);

module.exports = router;
`;

        return content;
    }

    generateValidator(modelName) {
        const content = `const { body, param, query } = require('express-validator');

const validate${modelName} = [
  // 这里添加具体的验证规则
  // 示例：
  // body('name').notEmpty().withMessage('名称不能为空'),
  // body('email').isEmail().withMessage('邮箱格式不正确'),

  // 可以根据模型字段动态生成验证规则
];

const validate${modelName}Id = [
  param('id').isInt().withMessage('ID必须是整数')
];

const validate${modelName}Query = [
  query('page').optional().isInt({ min: 1 }).withMessage('页码必须是正整数'),
  query('limit').optional().isInt({ min: 1, max: 100 }).withMessage('每页数量必须在1-100之间')
];

module.exports = {
  validate${modelName},
  validate${modelName}Id,
  validate${modelName}Query
};
`;

        return content;
    }

    async generateFiles(modelName) {
        try {
            // 确保目录存在
            await fs.ensureDir(this.config.output.controllersDir);
            await fs.ensureDir(this.config.output.routesDir);
            await fs.ensureDir(this.config.output.validatorsDir);

            // 生成控制器
            const controllerContent = this.generateController(modelName);
            const controllerPath = path.join(this.config.output.controllersDir, `${modelName}Controller.js`);
            await fs.writeFile(controllerPath, controllerContent, 'utf8');
            console.log(chalk.green(`✅ 生成控制器: ${modelName}Controller.js`));

            // 生成路由
            const routesContent = this.generateRoutes(modelName);
            const routesPath = path.join(this.config.output.routesDir, `${modelName}Routes.js`);
            await fs.writeFile(routesPath, routesContent, 'utf8');
            console.log(chalk.green(`✅ 生成路由: ${modelName}Routes.js`));

            // 生成验证器
            const validatorContent = this.generateValidator(modelName);
            const validatorPath = path.join(this.config.output.validatorsDir, `${modelName}Validator.js`);
            await fs.writeFile(validatorPath, validatorContent, 'utf8');
            console.log(chalk.green(`✅ 生成验证器: ${modelName}Validator.js`));

        } catch (error) {
            console.error(chalk.red('❌ 生成文件失败:'), error.message);
            throw error;
        }
    }

    async run() {
        try {
            console.log(chalk.blue('⚡ 开始生成 CRUD 代码...\n'));

            // 获取可用模型
            const models = await this.getAvailableModels();

            if (models.length === 0) {
                console.log(chalk.yellow('⚠️  没有找到可用的模型文件'));
                console.log(chalk.gray('请先运行模型同步工具生成模型文件'));
                return;
            }

            // 选择模型
            const selectedModel = await select({
                choices: models,
                message: '请选择要生成 CRUD 代码的模型:'
            });

            console.log(chalk.cyan(`\n📝 选择的模型: ${selectedModel}\n`));

            // 确认生成
            const confirmed = await confirm({
                message: '确认生成 CRUD 代码吗？这将覆盖现有文件。',
                default: false
            });

            if (!confirmed) {
                console.log(chalk.yellow('❌ 操作已取消'));
                return;
            }

            // 生成文件
            await this.generateFiles(selectedModel);

            console.log(chalk.green('\n🎉 CRUD 代码生成完成!'));
            console.log(chalk.gray('\n📋 生成的文件:'));
            console.log(chalk.gray(`  - 控制器: src/controllers/${selectedModel}Controller.js`));
            console.log(chalk.gray(`  - 路由: src/routes/${selectedModel}Routes.js`));
            console.log(chalk.gray(`  - 验证器: src/validators/${selectedModel}Validator.js`));

            console.log(chalk.yellow('\n💡 提示:'));
            console.log(chalk.gray('  1. 请在验证器中添加具体的验证规则'));
            console.log(chalk.gray('  2. 在 app.js 中注册路由'));
            console.log(chalk.gray('  3. 根据需要调整控制器逻辑'));

        } catch (error) {
            console.error(chalk.red('\n❌ CRUD 代码生成失败:'), error.message);
            throw error;
        }
    }
}

module.exports = new ExpressCrudGenerator();
